package cn.yll.web.config;

import cn.yll.api.conf.UserAuthorize;
import cn.yll.api.util.IpUtil;
import cn.yll.common.constant.MyConstants;
import cn.yll.common.exception.BsErrEnum;
import cn.yll.common.exception.BsException;
import cn.yll.common.module.RestModel;
import cn.yll.common.utils.JwtTokenUtil;
import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Objects;

/**
 * 接口用户权限认证
 * @author yangll
 */
@Slf4j
@Configuration
public class UserLoginInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String ip = IpUtil.getIpAddress(request);
        String ua = request.getHeader("user-agent");
        String url = request.getRequestURL().toString();
        if(!(handler instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod method = (HandlerMethod) handler;
        UserAuthorize authorize = method.getMethodAnnotation(UserAuthorize.class);
        if (Objects.isNull(authorize)) {
            authorize = method.getBeanType().getAnnotation(UserAuthorize.class);
        }
        Long userId = null;
        String jwtToken = request.getHeader(MyConstants.TOKEN_KEY);
        if (Objects.nonNull(authorize) && StringUtils.isBlank(jwtToken)) {
            //需要登录才能访问的接口
            return makeExpResponse(response, BsErrEnum.NEED_LOGIN, url, ip, ua);
        } else if (StringUtils.isNotBlank(jwtToken)) {
            if (StringUtils.isNotBlank(jwtToken)) {
                try {
                    userId = JwtTokenUtil.getUserIdByJwtToken(jwtToken);
                    request.setAttribute(MyConstants.LOGIN_USER_ID, userId);
                } catch (BsException e) {
                    return makeExpResponse(response, e.getBsErrEnum(), url, ip, ua);
                }
            }
        }
        log.info("用户={},{}请求:{},参数:{},ip={},{}", userId, request.getMethod(), url, JSON.toJSONString(request.getParameterMap()), ip, ua);
        return true;
    }

    private boolean makeExpResponse(HttpServletResponse response, BsErrEnum webEnum, String url, String ip, String ua) throws IOException {
        log.info(String.join("~~",webEnum.getMessage(), url, ip, ua));
        response.setContentType("application/json; charset=utf-8");
        response.setCharacterEncoding("UTF-8");
        response.getWriter().print(JSON.toJSONString(new RestModel<>(webEnum)));
        return false;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) {
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
    }

}
